package rawengine.physics;

import java.util.Iterator;
import java.util.Vector;

import rawengine.graphics.Texture;
import rawengine.math.Vector2f;
import rawengine.math.VectorMath2D;




public class ParticleEmitter {
	
		private static float PI_DIV_180 = 3.1415926535f / 180.0f;
	
		private Vector<Particle> particles;
		private Texture image;
		private Vector2f position;
		private float direction;
		private float length;
		private int max;
		private float alphaMin,alphaMax;
		private float minR,minG,minB,maxR,maxG,maxB;
		private int spread;
		private float velocity;
		private float scale;
		
		public ParticleEmitter(Texture image)
		{
			this.setImage(image);
			max = 100;
			length = 100;
			direction = 0;
			alphaMin = .99f; alphaMax = 1;
			minR = 0; maxR = 1;
			minG = 0; maxG = 1;
			minB = 0; maxB = 1;
			spread = 10;
			velocity = 1.0f;
			scale = 1.0f;
			position = new Vector2f();
			particles = new Vector<Particle>();
		}
		
		
		
		public void setPosition(float x, float y) 
		{ 
			position.setTo(x,y); 
		}
		
		public void setPosition(Vector2f vector) 
		{ 
			position = vector; 
		}
		
		public Vector2f getPosition() 
		{ 
			return position; 
		}
		
		public void setDirection(float angle) 
		{ 
			direction = angle; 
		}
		
		public float getDirection() 
		{ 
			return direction; 
		}
		
		public void setMax(int max) 
		{ 
			this.max = max; 
		}
		
		
		public void setAlphaRange(float min, float max)
		{
			alphaMin=min;
			alphaMax=max;
		}
		
		public void setColorRange(float minR, float minG, float minB, float maxR, float maxG, float maxB)
		{
			this.minR = minR; this.maxR = maxR;
			this.minG = minG; this.maxG = maxG;
			this.minB = minB; this.maxB = maxB;
		
		}
		
		public void setSpread(int spread) 
		{ 
			this.spread = spread; 
		}
		
		public void setLength(float length) 
		{ 
			this.length = length; 
		}
		
		public void setVelocity(float velocity) 
		{ 
			this.velocity = velocity; 
		}
		
		public void setScale(float scale) 
		{ 
			this.scale = scale; 
		}
		
		public float getScale()
		{
			return scale;
		}

		
		
		public void add()
		{
			
			float vx,vy;
			//create a new particle
			Particle particle = new Particle(getImage());
			particle.setPosition(position);
			
			//add some randomness to the spread
			float variation = (float)((Math.random() * spread) - spread/2) / 100.0f;
			//set linear velocity
			float dir = -getDirection();
			vx = (float)Math.cos( dir * PI_DIV_180) + variation;
			vy = (float)Math.sin( dir * PI_DIV_180) + variation;
			//System.out.println(vx + " " + vy);
			particle.setVelocity(new Vector2f(vx * velocity,vy * velocity));
			//set random color based on ranges
			float r = (float) (Math.random()*(maxR-minR)+minR);
			float g = (float) (Math.random()*(maxG-minG)+minG);
			float b = (float) (Math.random()*(maxB-minB)+minB);
			float a = (float) (Math.random()*(alphaMax-alphaMin)+alphaMin);
			particle.color[0] = r;
			particle.color[1] = g;
			particle.color[2] = b;
			particle.color[3] = a;
			//set the scale
			particle.setScale( scale );
			//add particle to the emitter
			particles.add(particle);
			//System.out.println(r + " " + g + " " + b + " " +a);
			
		}
		
		public void update()
		{
			
			
			if (particles.size() < max)
			{
			
				try {
					Thread.sleep(1);
					add();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			Iterator<Particle> it = particles.iterator();
			
			while(it.hasNext())
			{
				Particle p = (Particle)it.next();
				p.update();
				
				float distance = VectorMath2D.distance(p.getPosition(), position);
				if(distance > length)
				{
					
					p.setPosition(position);
				
				}
				
			}
			
		}

		public void draw()
		{
			Iterator<Particle> it = particles.iterator();
			while(it.hasNext())
			{
				
					((Particle)it.next()).draw();
				
			}
		}

		/**
		 * @param image the image to set
		 */
		public void setImage(Texture image) {
			this.image = image;
		}



		/**
		 * @return the image
		 */
		public Texture getImage() {
			return image;
		}
		

}
